<?php
namespace app\api\library;
use app\common\model\User;
use app\common\library\Token;
use think\helper\Str;
use think\Config;
use think\Session;
use think\Cookie;
use think\Validate;
use think\Db;
use think\Exception;
use think\Log;

class Auth{
    protected static $instance = null;
    protected $_error = '';
    protected $logined = false;
    protected $_user = null;
    //Token默认有效时长
    protected $keeptime = 0;
    //默认配置
    protected $config = [];
    protected $options = [];
    protected $allowFields = ['id','nickname', 'mobile','avatar','openid'];

    public function __construct($options = [])
    {
        $this->options = array_merge($this->config, $options);
    }

    /**
     *
     * @param array $options 参数
     * @return Auth
     */
    public static function instance($options = [])
    {
        if (is_null(self::$instance)) {
            self::$instance = new static($options);
        }
        return self::$instance;
    }
    /**
     * 获取登录用户的信息
     */
    public function __get($name)
    {
        return Session::get('spadmin_life_user.' . $name);
    }

    /**
     * 管理员登录
     *
     * @param string $username 用户名
     * @param string $password 密码
     * @param int    $keeptime 有效时长
     * @return  boolean
     */
    public function loginMobile($mobile, $keeptime = 0)
    {
        $admin = User::get(['mobile' => $mobile]);
        if (!$admin) {
            $this->setError('登录账号错误');
            return false;
        }
        if ($admin['status'] != '1') {
            $this->setError('登录账号错误');
            return false;
        }
        if($admin['is_verify'] != '1' ){
            $this->setError('登录账号错误');
            return false;
        }        
        $admin->login_time = time();
        $admin->login_ip = request()->ip();
        $admin->token = Str::uuid();
        $admin->save();
        Session::set("spadmin_life_user", $admin->toArray());
        $this->keeplogin($keeptime);
        return true;
    }
/**
     * 管理员登录
     *
     * @param string $username 用户名
     * @param string $password 密码
     * @param int    $keeptime 有效时长
     * @return  boolean
     */
    public function loginOpenid($openid, $keeptime = 0)
    {
        $admin = User::get(['openid' => $openid]);
        if (!$admin) {
            $this->setError('登录账号错误');
            return false;
        }
        if ($admin['status'] != '1') {
            $this->setError('登录账号错误');
            return false;
        }
        if($admin['is_verify'] != '1' ){
            $this->setError('登录账号错误');
            return false;
        }        
        $admin->login_time = time();
        $admin->login_ip = request()->ip();
        $admin->token = Str::uuid();
        $admin->save();
        Session::set("spadmin_life_user", $admin->toArray());
        $this->keeplogin($keeptime);
        return true;
    }
    /**
     * 自动登录
     * @return boolean
     */
    public function autologin()
    {
        $keeplogin = Cookie::get('lifespadminkeeplogin');
        if (!$keeplogin) {
            return false;
        }
        list($id, $keeptime, $expiretime, $key) = explode('|', $keeplogin);
        if ($id && $keeptime && $expiretime && $key && $expiretime > time()) {
            $admin = User::get($id);
            if (!$admin || !$admin->token) {
                return false;
            }
            //token有变更
            if ($key != md5(md5($id) . md5($keeptime) . md5($expiretime) . $admin->token . config('token.key'))) {
                return false;
            }
            
            Session::set("spadmin_life_user", $admin->toArray());
            //刷新自动登录的时效
            $this->keeplogin($keeptime);
            return true;
        } else {
            return false;
        }
    }
    /**
     * 检测是否登录
     *
     * @return boolean
     */
    public function isLogin()
    {
        if ($this->logined) {
            return true;
        }
        $admin = Session::get('spadmin_life_user');
        if (!$admin) {
            return false;
        }
        //判断是否同一时间同一账号只能在一个地方登录
        $my = User::get($admin['id']);
        if (!$my || $my['token'] != $admin['token']) {
            $this->logined = false; //重置登录状态
            Session::delete("spadmin_life_user");
            Cookie::delete("lifespadminkeeplogin");
            return false;
        }        
        $this->logined = true;
        return true;
    }
    /**
     * 刷新保持登录的Cookie
     *
     * @param int $keeptime
     * @return  boolean
     */
    protected function keeplogin($keeptime = 0)
    {
        if ($keeptime) {
            $expiretime = time() + $keeptime;
            $key = md5(md5($this->id) . md5($keeptime) . md5($expiretime) . $this->token . Config::get('token.key'));
            $data = [$this->id, $keeptime, $expiretime, $key];
            Cookie::set('lifespadminkeeplogin', implode('|', $data), 86400 * 365);
            return true;
        }
        return false;
    }
    /**
     * 退出登录
     */
    public function logout()
    {
        $admin = User::get(intval($this->id));
        if ($admin) {
            $admin->token = '';
            $admin->save();
        }
        $this->logined = false; //重置登录状态
        Session::delete('spadmin_life_user');
        Cookie::delete("lifespadminkeeplogin");
        return true;
    }

    



    /**
     * 兼容调用user模型的属性
     */
    public function __isset($name)
    {
        return isset($this->_user) ? isset($this->_user->$name) : false;
    }

    /**
     * 获取允许输出的字段
     * @return array
     */
    public function getAllowFields()
    {
        return $this->allowFields;
    }

    /**
     * 设置允许输出的字段
     * @param array $fields
     */
    public function setAllowFields($fields)
    {
        $this->allowFields = $fields;
    }

    /**
     * 设置错误信息
     *
     * @param string $error 错误信息
     * @return Auth
     */
    public function setError($error)
    {
        $this->_error = $error;
        return $this;
    }

    /**
     * 获取错误信息
     * @return string
     */
    public function getError()
    {
        return $this->_error ? $this->_error : '';
    }
}